<template>
    <div class="base-model" @contextmenu.native.prevent>
        <el-container class="container">
            <transition :name="`${init ? 'animate__animated ' : ''}`" enter-active-class="animate__fadeIn "
                        leave-active-class="animate__fadeOut " mode="out-in">
                <div class="dark-background" v-show="darkMode"/>
            </transition>
            <transition name="animate__animated " enter-active-class="animate__fadeInDown"
                        leave-active-class="animate__fadeOutUp animate__faster">
                <c_header :visible="showHeader" :sseStatus="sseConnectStatus" @openMenu="loginTo" v-show="showHeader"/>
            </transition>
            <transition name="animate__animated " enter-active-class="animate__slideInDown"
                        leave-active-class="animate__fadeOutUpBig animate__faster">
                <c_tagMenu v-show="showHeader" style="z-index: 1;"/>
            </transition>
            <el-drawer :show-close="false" :with-header="false" size="350px" v-model="showMenu" destroy-on-close
                       direction="ltr" class="menu-drawer forbid-select" @open="openMenu" @closed="close">
                <div class="flex-display-center menu-title-name">
                    <div @dblclick="logout">{{ webInfo.websiteName }}</div>
                </div>
                <c_menu class="c_menu" @click="click"/>
            </el-drawer>
            <el-main class="inner-main" ref="main">
                <el-config-provider :locale="zhCn" :message="{ max: 3 }">
                    <slot/>
                </el-config-provider>
            </el-main>
        </el-container>
        <el-drawer v-model="showMessageDialog" direction="rtl" size="50%" :show-close="false" :with-header="false"
                   @close="close" @open="openDialog" class="message forbid-select">
            <el-form inline :model="messageModel" class="e-page message-form form-auto-resize" @submit.native.prevent
                     spellcheck="false" ref="messageModelRef" :rules="rules" :validate-on-rule-change="false">
                <el-form-item label="收信人" prop="user">
                    <el-select v-model="messageModel.user" class="input-auto-resize" clearable
                               popper-class="normal-poper" placeholder="请选择收件人,为空发送全体">
                        <el-option :label="item.username" :value="item.sequence" v-for="(item, index) in messageUser"
                                   :key="index"/>
                    </el-select>
                </el-form-item>
                <el-form-item label="事件类型" prop="event">
                    <el-radio-group v-model="messageModel.event">
                        <el-radio :value="item.value" v-for="(item, index) in eventType" :key="index">
                            {{ item.label }}
                        </el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="消息类型" prop="event">
                    <el-radio-group v-model="disableMessageType" v-if="messageModel.event === 'update'" disabled>
                        <el-radio :value="1">消息</el-radio>
                        <el-radio :value="2">通知</el-radio>
                        <el-radio :value="3">弹窗</el-radio>
                    </el-radio-group>
                    <el-radio-group v-model="messageModel.messageType" v-else>
                        <el-radio :value="1">消息</el-radio>
                        <el-radio :value="2">通知</el-radio>
                        <el-radio :value="3">弹窗</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="标题" prop="title">
                    <el-input v-model="messageModel.title" class="input-auto-resize"
                              :disabled="messageModel.event === 'update'"/>
                </el-form-item>
                <el-form-item label="内容" prop="content">
                    <el-input v-model="messageModel.content" class="font-auto-resize" type="textarea" :rows="5"
                              resize="none" :disabled="messageModel.event === 'update'"/>
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button :icon="getIcon('close')" class="button-auto-resize" circle @click="showMessageDialog = false"
                           type="danger"/>
                <el-button :icon="getIcon('check')" class="button-auto-resize" circle @click="sendMessage"
                           type="primary" style="margin-left: 15px!important;"/>
            </template>
        </el-drawer>
        <setting v-model="showSetting"/>
    </div>
</template>

<script setup>
import {useEventListener} from "@vueuse/core"
import {useRequest, usePageRefresh, useModalSize} from "@usehook"
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import router from "@/router"
import {setPageStyle} from "@/utils/setting"
import {pbDecrypt, getIcon} from "@/utils/tools"
import login from "@/components/login"
import instance, {storeToRefs} from "@/pinia"
import {addEmitterListener} from "@/utils/eventbus"
import {startSSE} from "@/utils/sseConnection"
import {apiPrefix, publicKey} from "@/utils/constant"

const openMenu = () => {
    useModalSize()
}

let sseConnectStatus = startSSE()

window.addEventListener("focus", () => {
    if (!sseConnectStatus.value) {
        sseConnectStatus = startSSE()
    }
})

const {mainStore, userStore, tagMenuStore} = instance

const close = () => {
    useModalSize(false)
}

let showSetting = $ref(false)

const disableMessageType = 3

// 网站基础信息
let webInfo = $ref({
    email: "",
    icpNumber: "",
    gaNumber: "",
    websiteName: "",
    name: "",
    captcha: false,
    allowUserPwd: false,
    expireTime: 60,
    domain: ""
})

// 是否显示目录
let showMenu = $ref(false)
let messageModel = $ref({user: "", event: "notice", title: "", content: "", messageType: 1})
let showMessageDialog = $ref(false)
let messageUser = $ref([])
let eventType = $ref([{label: "普通", value: "notice"}, {label: "更新", value: "update"}])
let messageModelRef = $ref(null)
// 获取基础数据
const getData = () => {
    useRequest({url: "/loginfo/getData"}).then((resp) => {
        if (resp && resp.status) {
            const data = resp.data
            webInfo.name = data.name ? data.name : "松不渝"
            webInfo.captcha = data.captcha !== '0'
            webInfo.icpNumber = data['icp.number']
            webInfo.gaNumber = data['ga.number']
            webInfo.websiteName = data['website.name']
            webInfo.allowUserPwd = data['allow.user.password.console'] === "1"
            webInfo.expireTime = parseInt(data['qr.code.expire.second']) || 60
            webInfo.domain = data.domain
            webInfo.email = data.email
            publicKey.value = data.publicKey
            localStorage.setItem("rsaPublicKey", data.publicKey)
            mainStore.setWebInfo(webInfo)
        }
    })
}

let rules = computed(() => {
    return messageModel.event === "notice" ? {
        content: [{
            required: true,
            message: '消息内容不能为空',
            trigger: []
        }]
    } : {}
})

// 是否是暗黑模式
let darkMode = $ref(false)
// 是否初始化
let init = $ref(false)

let showHeader = $ref(false)

// 用户信息
const {islogin} = storeToRefs(userStore)

watch(() => router.currentRoute.value.path, (path) => {
    showHeader = path !== "/"
})

watch(islogin, (login) => {
    if (login) useRequest.post(apiPrefix + "/reg/user/check").then(response => {
        if (response && response.status) {
            const avatar = JSON.parse(pbDecrypt(response.data)).avatar
            if (avatar) userStore.updateUserAvatar(avatar)
        }
    })
}, {immediate: true})

// 显示登录框
const loginTo = () => {
    if (islogin.value) {
        showMenu = true
    } else {
        login()
    }
}

addEmitterListener("showLogin", () => {
    loginTo()
})

watch(() => messageModel, () => {
    nextTick(() => {
        messageModelRef.clearValidate()
    })
}, {deep: true})

const keyDown = (e) => {
    const {key, keyCode, ctrlKey, altKey} = e
    if (key === "F9" && islogin.value) {
        showMessageDialog = true
    }

    if (key === "F12") {
        if (islogin.value) showSetting = !showSetting
    }

    if ((key === 'KeyE' || keyCode === 69) && (ctrlKey || altKey)) {
        e.preventDefault(); //关闭浏览器快捷键
        if (islogin.value) showMenu = !showMenu
    }

    const focus = document.activeElement === document.body || document.activeElement === document.querySelector(".el-drawer__sr-focus");
    if ((key === 'Tab' || keyCode === 9) && focus && (!useModalSize.get() || showMenu)) {
        e.preventDefault(); //关闭浏览器快捷键
        if (islogin.value) showMenu = !showMenu
    }
}

const openDialog = () => {
    useRequest({url: "/sse/getUserName"}).then((resData) => {
        messageUser = resData.data || []
    })
    useModalSize()
}

const sendMessage = () => {
    const eventName = messageModel.event
    const message = JSON.stringify({
        title: messageModel.title,
        content: messageModel.content,
        messageType: messageModel.messageType
    })
    messageModelRef.validate().then(() => {
        useRequest.post({url: "/sse/sendMessage", clientId: messageModel.user, eventName, message}).then(resData => {
            if (resData && resData.status) {
                // useElMessage("消息发送成功")
                messageModel = {user: "", event: "notice", title: "", content: "", messageType: 1}
                showMessageDialog = false
            }
        })
    }).catch(() => {
    })
}

usePageRefresh((type) => {
    if (type === 'refresh') {
        localStorage.setItem("refresh", new Date().getTime() + "")
        localStorage.setItem("showCalendarInfo", true)
        localStorage.setItem("lastPageTitle", router.currentRoute.value.meta.title)
    } else {
        localStorage.setItem("close", new Date().getTime() + "")
    }
})

onMounted(() => {
    addEventListener("keydown", keyDown)
    setPageStyle()
    darkMode = document.documentElement.classList.contains("dark")
    setTimeout(() => {
        init = true
    })
    // 获取基础数据
    getData()
    // 禁用保存
    useEventListener(document, 'keydown', (event) => {
        if (event.code === 'KeyS' && event.ctrlKey) {
            event.preventDefault()
        }
    })
})

// 监听暗黑模式,切换时全局广播
addEmitterListener('darkMode', (evt) => {
    darkMode = !evt
})

const logout = () => {
    showMenu = false
    router.replace("/")
    setTimeout(() => {
        userStore.logout()
        tagMenuStore.clearTagMenu()
    }, 200)
}

const click = () => {
    showMenu = false
}
</script>

<style lang="scss" scoped>
:deep(.inner-main) {
    height: var(--main-height); //calc(100vh - v-bind(height));
    padding: 0;
    overflow: hidden;
    color: var(--font-color);
    z-index: 1;

    @media screen and (min-width: 200px) and (max-width: 900px) {
        width: 100% !important;
    }

    @media screen and (min-width: 200px) and (max-width: 400px) {
        max-height: calc(100vh - 65px);
    }
}

:deep(.container) {
    overflow: hidden;
    width: 100vw;
    height: 100vh;
    position: relative;
    background: transparent url("@/assets/image/bg-sm.jpg") no-repeat 50%;
    background-size: cover;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        background-position: 50% !important;
    }
}

:deep(.container::before) {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: url("@/assets/image/background.jpg");
    /* 初始时与父元素背景相同 */
    background-size: cover;
    opacity: 0;
    /* 初始时隐藏伪元素 */
}

.dark-background {
    overflow: hidden;
    width: 100vw;
    height: 100vh;
    position: absolute;
    background: transparent url("@/assets/image/background.jpg") no-repeat 50%;
    background-size: cover;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        background-position: 65% !important;
    }
}

:deep(.base-model) {
    width: 100%;
    height: 100%;
    overflow: auto;
    position: relative;
}

/* 定义一个名为rotate的动画 */
@keyframes rotate {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}

:deep(.menu-drawer.el-drawer .el-drawer__body) {
    padding: 0
}

:deep(.c_menu) {
    height: calc(100vh - 20px - var(--font-size) * 2);
}

:deep(.menu-title-name) {
    height: calc(var(--font-size) * 2) !important;
    margin: 10px 0 !important;
    font-size: calc(var(--font-size) * 2) !important;
    color: var(--font-color);
    font-family: fojiya, cursive, monospace;
    font-weight: bold;
}

:deep(.message-form .el-form-item__error) {
    top: 10px;
    right: 10px;
    left: unset;
    font-size: calc(var(--font-size) - 2px);
    pointer-events: none;
}
</style>

<style>
.message .el-drawer__footer {
    padding: 10px 20px !important;
}
</style>
